﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Globalization;
using System.IO;
using aaaSoft.Helpers;
using System.Reflection;
using CodeMonkeyToolApi;

namespace CodeMonkeyToolsLauncher
{
    public partial class MainForm : Form
    {
        //Metro UI默认颜色
        private Color MetroUIDefaultColor = Color.FromArgb(38, 160, 218);

        GlobalizationHelper globalizationHelper;

        List<AbstractCodeMonkeyTool> toolList;
        IDictionary<String, List<AbstractCodeMonkeyTool>> toolTypeToolListDict;

        public MainForm()
        {
            InitializeComponent();
            toolList = new List<AbstractCodeMonkeyTool>();
            toolTypeToolListDict = new Dictionary<String, List<AbstractCodeMonkeyTool>>();
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            lblVersion.Text = Application.ProductVersion;

            globalizationHelper = new GlobalizationHelper();
            globalizationHelper.ManagedControlList.Add(this);
            globalizationHelper.ResourceFilePath = "CodeMonkeyToolsLauncher.Resources.Launcher";
            globalizationHelper.Init();

            lsbLanguageSwitch.DefaultCulture = globalizationHelper.CurrentCulture;
            lsbLanguageSwitch.InitLanguageList(Application.StartupPath);

            scanToolsFolder();
            addToolTypeToToolTypeDict();
            addToolTypeToList();
            addToolTypeToolToContainer();
        }

        private void lsbLanguageSwitch_LanguageChanged(object sender, EventArgs e)
        {
            globalizationHelper.CurrentCulture = lsbLanguageSwitch.CurrentCulture;
            
            lbToolTypes.Items.Clear();
            lbToolTypes.Items.Add(globalizationHelper.GetString("AllTypes"));
            lbToolTypes.SelectedIndex = 0;

            addToolTypeToToolTypeDict();
            addToolTypeToList();
        }
        
        private void lbToolTypes_SelectedIndexChanged(object sender, EventArgs e)
        {            
            addToolTypeToolToContainer();
        }

        //扫描工具目录
        private void scanToolsFolder()
        {
            toolTypeToolListDict.Clear();

            DirectoryInfo dir = new DirectoryInfo(Path.Combine(Application.StartupPath, "Tools"));
            if (!dir.Exists)
            {
                return;
            }

            var directoryInfoArray = dir.GetDirectories();
            foreach (var directoryInfo in directoryInfoArray)
            {
                var fileInfoArray = directoryInfo.GetFiles("*.dll");
                foreach (var fileInfo in fileInfoArray)
                {
                    Assembly assembly = Assembly.LoadFile(fileInfo.FullName);
                    Type[] types = assembly.GetTypes();
                    foreach (var type in types)
                    {
                        if (type.IsSubclassOf(typeof(AbstractCodeMonkeyTool)))
                        {
                            var constructorInfoArray = type.GetConstructors();

                            AbstractCodeMonkeyTool tool = (AbstractCodeMonkeyTool)constructorInfoArray[0].Invoke(new Object[] { });
                            lock (toolList)
                            {
                                toolList.Add(tool);
                            }
                        }
                    }
                }
            }
        }

        //添加工具类别到工具类别字典中
        private void addToolTypeToToolTypeDict()
        {
            lock (toolTypeToolListDict)
            {
                toolTypeToolListDict.Clear();
                foreach (var tool in toolList)
                {
                    String toolType = tool.GetToolType(globalizationHelper.CurrentCulture);
                    List<AbstractCodeMonkeyTool> toolTypeList;
                    if (toolTypeToolListDict.ContainsKey(toolType))
                    {
                        toolTypeList = toolTypeToolListDict[toolType];
                    }
                    else
                    {
                        toolTypeList = new List<AbstractCodeMonkeyTool>();
                        toolTypeToolListDict.Add(toolType, toolTypeList);
                    }
                    toolTypeList.Add(tool);
                }
            }
        }

        //添加工具类别到类别列表中
        private void addToolTypeToList()
        {
            lock (toolTypeToolListDict)
            {
                foreach (var key in toolTypeToolListDict.Keys)
                {
                    lbToolTypes.Items.Add(key);
                }
            }
        }

        //添加选中工具类别的工具到容器中
        private void addToolTypeToolToContainer()
        {
            flpApplicationIcon.Controls.Clear();

            List<AbstractCodeMonkeyTool> toolList = new List<AbstractCodeMonkeyTool>();
            lock (toolTypeToolListDict)
            {
                if (lbToolTypes.SelectedIndex == 0)
                {
                    foreach (var key in toolTypeToolListDict.Keys)
                    {
                        toolList.AddRange(toolTypeToolListDict[key]);
                    }
                }
                else
                {
                    String toolType = lbToolTypes.SelectedItem.ToString();
                    if (toolTypeToolListDict.ContainsKey(toolType))
                    {
                        toolList.AddRange(toolTypeToolListDict[toolType]);
                    }
                }
            }
            foreach (var tool in toolList)
            {
                addToolToContainer(tool);
            }
        }

        //添加工具到容器中
        private void addToolToContainer(AbstractCodeMonkeyTool tool)
        {
            //定义工具图标的大小
            Size appIconSize =new System.Drawing.Size(128, 128);

            Panel panel = new Panel();
            panel.Size = appIconSize;
            PictureBox pb = new PictureBox();
            pb.Size = appIconSize;

            panel.Controls.Add(pb);
            flpApplicationIcon.Controls.Add(panel);

            Image appIcon = tool.GetToolIcon(globalizationHelper.CurrentCulture);
            if (appIcon == null)
            {
                appIcon = new Bitmap(appIconSize.Width, appIconSize.Height);
                RectangleF rect = new RectangleF(new PointF(0, 0), appIcon.Size);

                Graphics g = Graphics.FromImage(appIcon);
                g.FillRectangle(new SolidBrush(MetroUIDefaultColor), rect);

                Font font = new Font("Microsoft YaHei", rect.Width * 0.08F);

                StringFormat sf = new StringFormat();
                sf.Alignment = StringAlignment.Near;
                sf.LineAlignment = StringAlignment.Far;

                RectangleF rectString = rect;

                Single sp = rect.Width * 0.03F;

                rectString.X += sp;
                rectString.Y += sp;
                rectString.Width -= 2 * sp;
                rectString.Height -= 2 * sp;

                g.DrawString(tool.GetToolName(globalizationHelper.CurrentCulture), font, Brushes.White, rectString, sf);
            }
            pb.Image = appIcon;
            pb.SizeMode = PictureBoxSizeMode.StretchImage;

            //绑定事件
            pb.MouseClick += new MouseEventHandler(delegate(object sender, MouseEventArgs e)
            {
                tool.Start();
            });

            pb.MouseDown += new MouseEventHandler(delegate(object sender, MouseEventArgs e)
            {
                Size PreferredSize = pb.PreferredSize;
                Size ClientSize = pb.ClientSize;
                Single scaleFactor = 0.98F;

                pb.Scale(new SizeF(scaleFactor * PreferredSize.Width / ClientSize.Width, scaleFactor * PreferredSize.Height / ClientSize.Height));
            });
            pb.MouseUp += new MouseEventHandler(delegate(object sender, MouseEventArgs e)
            {
                Size PreferredSize = pb.PreferredSize;
                Size ClientSize = pb.ClientSize;
                Single scaleFactor = 1F;

                pb.Scale(new SizeF(scaleFactor * PreferredSize.Width / ClientSize.Width, scaleFactor * PreferredSize.Height / ClientSize.Height));
            });
        }
    }
}
